#ifndef BASE_ARMOR_DETECTOR_H
#define BASE_ARMOR_DETECTOR_H

#include <numeric>
#include <opencv2/opencv.hpp>
#include <vector>
#include <memory>

#include "armor_detector_types.h"

// 前向声明
class NumberClassifier;
class LightCornerCorrector;
class ArmorDetectorDebug;

class ArmorDetector {
public:
    ArmorDetector();
    ~ArmorDetector();

    // 从JSON配置文件加载参数
    void loadConfig(const std::string& config_path);

    // 图像预处理方法 - 实现二值化
    cv::Mat preprocessImage(const cv::Mat& input, int threshold = -1);

    // 查找灯条
    std::vector<LightBar> findLights(const cv::Mat& bin_img, const cv::Mat& src_img) const;

    // 匹配灯条形成装甲板（包含角点优化）
    std::vector<Armor> matchLights(const cv::Mat& src_img, const std::vector<LightBar>& lights) const;

    // 识别装甲板上的数字
    void recognizeArmorNumbers(const cv::Mat& src_img, std::vector<Armor>& armors);

    // 在图像上绘制装甲板（始终显示）
    static void drawArmors(cv::Mat& image, const std::vector<Armor>& armors);

    // 显示调试信息（根据配置文件决定是否显示）
    void showDebugInfo(const cv::Mat& originalImage,
                      const cv::Mat& binaryImage,
                      const std::vector<LightBar>& lights,
                      const std::vector<Armor>& armors);

    // 获取二值化图像
    cv::Mat getBinaryImage() const;

    // 获取当前二值化阈值
    int getBinaryThreshold() const { return binary_threshold_; }

    // 获取调试状态
    bool isDebugEnabled() const { return debug_enabled_; }

private:
    int binary_threshold_;  // 二值化阈值
    cv::Mat binary_image_;  // 存储二值化后的图像
    EnemyColor detect_color_; // 要检测的装甲板颜色
    bool debug_enabled_;    // 是否启用调试模式

    // 灯条参数
    LightParams light_params_{};

    // 装甲板参数
    ArmorParams armor_params_{};

    // 数字识别器
    std::unique_ptr<NumberClassifier> classifier_;

    // 角点优化器
    std::unique_ptr<LightCornerCorrector> corner_corrector_;

    // 调试显示模块
    std::unique_ptr<ArmorDetectorDebug> debug_visualizer_;

    // 辅助函数：判断是否为灯条
    bool isLight(const LightBar& light) const;

    // 辅助函数：判断是否为装甲板
    ArmorType isArmor(const LightBar& light_1, const LightBar& light_2) const;

    // 辅助函数：检查两个灯条之间是否包含其他灯条
    bool containLight(size_t i, size_t j, const std::vector<LightBar>& lights) const;

    // 辅助函数：计算两点间距离
    static float calculateDistance(const cv::Point2f& point1, const cv::Point2f& point2);

    // 辅助函数：计算两点间中心点
    static cv::Point2f calculateCenter(const cv::Point2f& point1, const cv::Point2f& point2);
};

#endif //BASE_ARMOR_DETECTOR_H
